/*
公共函数
 */

const axios = require('axios')
const Layer = require('./layer.js')
const electron = require('electron')
const path = require('path')

class C {
    constructor() {
        // 加载配置文件（配置文件统一从缓存中获取，以便后期修改）
        this.Conf = this.getConf()
    }
    /*
     * 设置缓存
     */
    setLocalStorage(name, data) {
        data ? localStorage.setItem(name, JSON.stringify(data)) : localStorage.removeItem(name)
    }

    /*
     * 获取缓存
     * 支持二级获取
     */
    getLocalStorage(name) {
        name = name.split('.')
        // 获取数据
        let data = JSON.parse(localStorage.getItem(name[0]))
        return name[1] ? data[name[1]] : data
    }

    /*
     * 判断是否在数组中存在
     * @author: huang
     * 支持多个属性判断
     */
    inarray(obj, array) {
        let key = -1
        array.forEach((row, index) => {
            let ishave = true
            for (let i in obj) {
                if (row[i] != obj[i]) {
                    ishave = false
                }
            }
            if (ishave) key = index
        })
        return key
    }
    /*
     * 删除一行
     * @author: 黄
     */
    deleterow(index, array) {
        array.splice(index, 1)
    }

    /*
     * 关闭窗口
     * @author: 黄
     */
    closewin() {
        const electron = require('electron')
        const win = electron.remote.getCurrentWindow()
        win.close()
    }

    /*
     * 防止重复点击
     */
    openLoading(url) {
        let loadUrl = 'loading' + url
        let setTime = 'settime' + url
        // 默认延时1秒自动关闭(开启此功能表示只要数据请求不成功那么在1秒内是不允许再次请求的)
        if (!this[setTime]) {
            this[setTime] = setTimeout(() => {
                delete this[loadUrl]
                delete this[setTime]
            }, 1000)
        }
        if (this[loadUrl]) return false
        this[loadUrl] = true
        return true
    }

    closeLoading(url) {
        let loadUrl = 'loading' + url
        let setTime = 'settime' + url
        delete this[loadUrl]
        clearTimeout(this[setTime])
        delete this[setTime]
    }

    /*
     * 简单对象深拷贝
     * 注：不能拷贝函数
     */
    copy(obj) {
        return JSON.parse(JSON.stringify(obj))
    }
    /*
     * 简单继承函数
     */
    assign(objA, objB) {
        return Object.assign({}, objA, objB)
    }

    /*
     * 较复杂的深拷贝（可拷贝函数）
     */
    deepCopy(obj) {}

    /*
     * 调试函数
     */
    e(res) {
        console.log(res)
        return false
    }

    /*********************新式页面弹窗及传参*********************/
    openBrowserWindow(url, data, options) {
        let that = this
        options = options || {}
        // 开始设置webpack的热更新
        // 暂时的思路是这样（useSpa: false-->使用普通路径,useSpa: true-->使用spa路径url即路由spaModel默认为index，即index下的路由）
        let spaModel = options.spaModel || 'index'
        let modalPath
        // 先判断是否spa模式
        if (options.useSpa) {
            modalPath = process.env.NODE_ENV === 'development' ?
                'http://localhost:8080/' + spaModel + '.html#' + url :
                path.join(this.Conf.root, 'html/dist/', spaModel) + '.html#' + url
            /*modalPath = path.join(this.Conf.root, 'html/dist/', spaModel)
            modalPath += '.html#'
            modalPath += url*/
        } else {
            modalPath = process.env.NODE_ENV === 'development' ? 'http://localhost:8080/' + url : path.join(this.Conf.root, url)
            // modalPath = path.join(this.Conf.root, url)
        }
        // let modalPath = path.join(this.Conf.root, url)

        return new Promise((resolve, reject) => {
            // let nowwindow = electron.remote.BrowserWindow.getFocusedWindow() （暂时不设置父窗口模式）
            let opt = {
                width: 800,
                height: 600,
                show: false
            }
            if (process.env.NODE_ENV === 'development') opt.webPreferences = { webSecurity: false }
            opt = Object.assign(opt, options)
            let win = new electron.remote.BrowserWindow(opt)
            let sendId = 'send_' + win.id
            let receiveId = 'receive_' + win.id

            // 设置传参
            data = data || {}
            that.setLocalStorage(sendId, data)
            win.on('close', function() {
                // 删除缓存
                let receiveData = that.getLocalStorage(receiveId)
                resolve(receiveData)
                that.setLocalStorage(sendId)
                that.setLocalStorage(receiveId)
                win = null
            })
            // 自适应大小
            win.on('resize', () => {
                const [width, height] = win.getContentSize()
                for (let wc of electron.remote.webContents.getAllWebContents()) {
                    // Check if `wc` belongs to a webview in the `win` window.
                    if (wc.hostWebContents &&
                        wc.hostWebContents.id === win.webContents.id) {
                        wc.setSize({
                            normal: {
                                width: width,
                                height: height
                            }
                        })
                    }
                }
            })
            if (options && options.openDevTools) win.webContents.openDevTools()
            win.loadURL(modalPath)
            win.show()
            /*win.once('ready-to-show', () => {
                win.show()
            })*/
        }).catch((e) => {
            console.log(e)
            Layer.error('未知错误！')
        })
    }
    closeBrowserWindow(data, win) {
        win = !win ? electron.remote.getCurrentWindow() : win
        data = data || {}
        this.setLocalStorage('receive_' + win.id, data)
        win.close()
    }
    getDatas() {
        let win = electron.remote.getCurrentWindow()
        return this.getLocalStorage('send_' + win.id)
    }
    /*********************新式页面弹窗及传参*********************/


    // 以下兼容H.js

    /*
     * 重构ajax请求
     * 只输出成功数据，错误数据在此屏蔽或统一提示
     * 考虑加入防止重复点击
     * url:string,data:json,option:json
     * output: data
     */
    async _ajax(url, data, type, option) {
        // 首先进行基础配置
        type = type || 'get'
        let opt = type == 'get' ? { params: data } : { data: data }
        opt = Object.assign(opt, {
            url: url,
            method: type,
            baseURL: this.Conf.domain
        }, option)
        // 暂时用自己写的防止重复点击
        if (!this.openLoading(url)) return false
        // Layer.openLoading() 暂时不用elementui的loading，用的时候开启即可
        let res = await axios(opt).catch(function(error) {
            console.log(error)
            // Layer.error('网络错误，请稍候再试！')
        })
        // Layer.closeLoading()
        this.closeLoading(url)
        // 暂时只允许200请求，其他的先报网络错误
        return res && res.status == 200 ? res.data : Layer.error('网络错误，请稍候再试！')
    }

    /****************以上为通用，以下为本项目使用****************/

    /*
     * 加载配置文件
     */
    getConf() {
        return require('../../config/config.js')
    }

    /*
     * 成功提示
     */
    success(str) {
        Layer.success(str)
    }

    /*
     * 错误提示
     */
    error(str) {
        Layer.error(str)
    }

    /*
     * 提示框
     */
    confirm(str, fun) {
        Layer.confirm(str, fun)
    }

    /*
     * prompt
     */
    prompt(tips, fun) {
        Layer.prompt(tips, fun)
    }

    /*
     * 时间格式化函数
     */
    times(unix) {
        let tm = unix ? new Date(unix * 1000) : new Date()
        let yy = tm.getFullYear()
        let mm = tm.getMonth() < 9 ? '0' + (tm.getMonth() + 1) : tm.getMonth() + 1
        let dd = tm.getDate() < 10 ? '0' + tm.getDate() : tm.getDate()
        let hh = tm.getHours() < 10 ? '0' + tm.getHours() : tm.getHours()
        let ii = tm.getMinutes() < 10 ? '0' + tm.getMinutes() : tm.getMinutes()
        let ss = tm.getSeconds() < 10 ? '0' + tm.getSeconds() : tm.getSeconds()
        return yy + '-' + mm + '-' + dd + ' ' + hh + ':' + ii + ':' + ss
    }

    time(unix) {
        let tm = unix ? new Date(unix * 1000) : new Date()
        let yy = tm.getFullYear()
        let mm = tm.getMonth() < 9 ? '0' + (tm.getMonth() + 1) : tm.getMonth() + 1
        let dd = tm.getDate() < 10 ? '0' + tm.getDate() : tm.getDate()
        return yy + '-' + mm + '-' + dd
    }

    /*
     * 制作通用ajax传输
     * 作用带自动过滤错误提示，（thinkjs的错误提示）
     * 带token验证方式
     */
    async ajax(url, data, type, option) {
        // 发送请求前对比机器码是否正确（如果有token对比，没有就忽略）
        let token = this.getLocalStorage('usertoken')
        if (token) {
            const machine = require('node-machine-id')
            let machineid = machine.machineIdSync()
            let headJson = JSON.parse(Buffer.from(token.split('.')[0], 'base64').toString())
            if (headJson.machineid != machineid) {
                Layer.error('非法登陆！')
                // 删除缓存
                C.setLocalStorage('usertoken')
                return false
            }
            // 如果机器码审核通过，简单加密
            // 获取本地ip
            token = Buffer.from(token + '.' + url).toString('base64')
            option = option || {}
            option.headers = Object.assign({}, { 'token': token }, option.headers)
        }

        let res = await this._ajax(url, data, type, option)
        // thinkjs通用过滤
        if (res && res.errno > 0) {
            if (res.errno == 1000) {
                Layer.error(res.errmsg)
                return false
            } else {
                Layer.error('未知错误！')
                return false
            }
        } else {
            return res
        }
    }


    /*
     * 加减乘除四则运算
     */
    //加
    accAdd(arg1, arg2) {
        var r1, r2, m
        try { r1 = arg1.toString().split('.')[1].length } catch (e) { r1 = 0 }
        try { r2 = arg2.toString().split('.')[1].length } catch (e) { r2 = 0 }
        m = Math.pow(10, Math.max(r1, r2))
        return (this.accMul(arg1, m) + this.accMul(arg2, m)) / m
    }
    //减
    accSub(arg1, arg2) {
        var r1, r2, m
        try { r1 = arg1.toString().split('.')[1].length } catch (e) { r1 = 0 }
        try { r2 = arg2.toString().split('.')[1].length } catch (e) { r2 = 0 }
        m = Math.pow(10, Math.max(r1, r2))
        return (this.accMul(arg1, m) - this.accMul(arg2, m)) / m
    }
    //乘
    accMul(arg1, arg2) {
        var m = 0,
            s1 = arg1.toString(),
            s2 = arg2.toString()
        try { m += s1.split('.')[1].length } catch (e) { console.log(e) }
        try { m += s2.split('.')[1].length } catch (e) { console.log(e) }
        return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
    }
    //除
    accDiv(arg1, arg2) {
        var t1 = 0,
            t2 = 0,
            r1, r2
        try { t1 = arg1.toString().split('.')[1].length } catch (e) { console.log(e) }
        try { t2 = arg2.toString().split('.')[1].length } catch (e) { console.log(e) }
        r1 = Number(arg1.toString().replace('.', ''))
        r2 = Number(arg2.toString().replace('.', ''))
        return (r1 / r2) * Math.pow(10, t2 - t1)
    }

    /*
     * excel导出数据公共函数
     * header = {worknum:'工号', name: '姓名', id: '编号'}
     * data = [{worknum:'11', name: 'aa', id: '12'}]
     */
    async excel(name, header, data) {
        const xlsx = require('node-xlsx')
        const fs = require('fs')
        const dialog = top.require('electron').remote.dialog
        const options = {
            title: '导出数据到excel-美易通',
            defaultPath: name + '.xlsx',
            filters: [
                { name: 'excel文档', extensions: ['xlsx', 'xls'] }
            ]
        }
        dialog.showSaveDialog(options, async(filename) => {
            if (filename) {
                if (data) {
                    // 根据header制作出表格数据
                    let allData = []
                    let a = []
                    for (var key in header) {
                        if (typeof header[key] == 'string') {
                            a.push(header[key])
                        } else {
                            a.push(header[key].value)
                        }
                    }
                    allData.push(a)
                    data.forEach((row) => {
                        let s = []
                        for (var key in header) {
                            if (typeof header[key] == 'object' && typeof header[key].fun == 'function') {
                                s.push(header[key].fun(row[key]))
                            } else {
                                s.push(row[key])
                            }
                        }
                        allData.push(s)
                    })
                    var buffer = xlsx.build([{ name: name, data: allData }])
                    fs.writeFile(filename, buffer, 'binary', () => {
                        this.success('导出成功！')
                    })
                }
            }
        })
    }
}


module.exports = new C